using System;
using System.Data;

namespace ERP.Classes
{
	/*
	 * This class provides database-like operations to simulate a real
	 * data source. The class generates sample data and uses a
	 * fixed set of commands.
	 */
	public class SampleDb
	{
		private const string m_sSelectCmd = "select ";
		private const string m_sUpdateCmd = "update ";

		public class SampleDbResultSet
		{
			public struct MetaData
			{
				public string  name;
				public Type    type;
				public int    maxSize;
			}

			public int  recordsAffected;
			public MetaData[]  metaData;
			public object[,]  data;
		}

		private SampleDbResultSet m_resultset = null;

		public void Execute(string sCmd, out SampleDbResultSet resultset)
		{
			/*
			 * The sample code simulates SELECT and UPDATE operations.
			 */
			if (0 == String.Compare(sCmd, 0, m_sSelectCmd, 0, m_sSelectCmd.Length, true))
			{
				executeSelect(out resultset);
			}
			else if (0 == String.Compare(sCmd, 0, m_sUpdateCmd, 0, m_sUpdateCmd.Length, true))
			{
				executeUpdate(out resultset);
			}
			else
				throw new NotSupportedException("Command string was not recognized");
		}

		private void executeSelect(out SampleDbResultSet resultset)
		{
			// If no sample data exists, create it.
			if (m_resultset == null)
				resultsetCreate();

			// Return the sample results.
			resultset = m_resultset;
		}

		private void executeUpdate(out SampleDbResultSet resultset)
		{
			// If no sample data exists, create it.
			if (m_resultset == null)
				resultsetCreate();

			// Change a row to simulate an update command.
			m_resultset.data[2,2] = 4199;

			// Create a result set object that is empty except for the RecordsAffected field.
			resultset = new SampleDbResultSet();
			resultset.recordsAffected = 1;
		}

		private void resultsetCreate()
		{
			m_resultset = new SampleDbResultSet();

			// RecordsAffected is always a zero value for a SELECT.
			m_resultset.recordsAffected = 0;

			const int numCols = 3;
			m_resultset.metaData = new SampleDbResultSet.MetaData[numCols];
			resultsetFillColumn(0, "id", typeof(Int32), 0);
			resultsetFillColumn(1, "name", typeof(String), 64);
			resultsetFillColumn(2, "orderid", typeof(Int32), 0);
      
			m_resultset.data = new object[5, numCols];
			resultsetFillRow(0, 1, "Biggs", 2001);
			resultsetFillRow(1, 2, "Brown", 2121);
			resultsetFillRow(2, 3, "Jones", 2543);
			resultsetFillRow(3, 4, "Smith", 2772);
			resultsetFillRow(4, 5, "Tyler", 3521);
		}

		private void resultsetFillColumn(int nIdx, string name, Type type, int maxSize)
		{
			m_resultset.metaData[nIdx].name    = name;
			m_resultset.metaData[nIdx].type    = type;
			m_resultset.metaData[nIdx].maxSize  = maxSize;
		}

		private void resultsetFillRow(int nIdx, int id, string name, int orderid)
		{
			m_resultset.data[nIdx, 0] = id;
			m_resultset.data[nIdx, 1] = name;
			m_resultset.data[nIdx, 2] = orderid;
		}
	}
}
